package org.unt.logic;

import java.io.IOException;
import java.util.Enumeration;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.log4j.Appender;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

public class LoggingLogic {

    private static Logger logger = Logger.getLogger("LoggingLogic");

    public static String setLoggingLevelForLogger(String loggingLevel, String loggerName) {

        if (loggerName == null) {
            throw new IllegalArgumentException("Parameter 'loggerName' cannot be null");
        }

        if (loggerName == null) {
            throw new IllegalArgumentException("Parameter 'loggingLevel' cannot be null");
        }

        Logger logger;

        if ("root".equalsIgnoreCase(loggerName)) {
            logger = Logger.getRootLogger();
        } else {
            logger = Logger.getLogger(loggerName);
        }

        if ("fatal".equalsIgnoreCase(loggerName)) {

            logger.setLevel(Level.FATAL);

        } else if ("error".equalsIgnoreCase(loggingLevel)) {

            logger.setLevel(Level.ERROR);

        } else if ("warn".equalsIgnoreCase(loggingLevel)) {

            logger.setLevel(Level.WARN);

        } else if ("info".equalsIgnoreCase(loggingLevel)) {

            logger.setLevel(Level.INFO);

        } else if ("debug".equalsIgnoreCase(loggingLevel)) {

            logger.setLevel(Level.DEBUG);

        } else {

            throw new IllegalArgumentException("No valid parameter 'loggingLevel' : " + loggingLevel);
        }

        return "Level set to '" + loggingLevel + "' for logger '" + loggerName + "'";
    }

    public static void configureLog4J() {

        ResourceBundle bundle = null;

        try {
            bundle = ResourceBundle.getBundle("runtime");
        } catch (MissingResourceException e) {
            logger.error("Cannot load 'runtime.properties' file");
            return;
        }

        // Add daily rolling file appender
        PatternLayout layout = new PatternLayout("%5p %d{HH:mm:ss,SSS} %F:%L -->> %m%n");
        String filename = bundle.getString("log.path.bath");
        String datePattern = "'.'yyyy-MM-dd";

        Logger rootLogger = Logger.getRootLogger();

        DailyRollingFileAppender appender = null;

        try {

            appender = new DailyRollingFileAppender(layout, filename, datePattern);
            appender.setName("pacteBatchAppender");

            rootLogger.addAppender(appender);
            rootLogger.setLevel(Level.INFO);

            Enumeration enu = rootLogger.getAllAppenders();
            while (enu.hasMoreElements()) {

                Appender app = (Appender) enu.nextElement();
                String name = app.getName();

                if (!"pacteBatchAppender".equals(name) && !"stdout".equals(name)) {
                    rootLogger.removeAppender(name);
                    logger.info("Appender removed   " + name);
                } else {
                    logger.info("Appender okay      " + name);
                }
            }
        } catch (IOException e) {
            logger.error("Cannot add appender 'pacteBatchAppender' to log4j programmatically");
            e.printStackTrace();
        }

        // Set logging levels
        Enumeration enumeration = bundle.getKeys();
        while (enumeration.hasMoreElements()) {
            String key = (String) enumeration.nextElement();
            String type = key.substring(0, key.indexOf("."));

            if ("logger".equals(type)) {

                String loggerName = key.substring("logger".length() + 1);
                String logLevel = bundle.getString(key);
                Logger loggerObj = Logger.getLogger(loggerName);

                if ("DEBUG".equals(logLevel)) {

                    loggerObj.setLevel(Level.DEBUG);
                    logger.info("Logger " + loggerName + "=DEBUG");

                } else if ("INFO".equals(logLevel)) {

                    loggerObj.setLevel(Level.INFO);
                    logger.info("Logger " + loggerName + "=INFO");
                }
            }
        }

    }
}
